home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / U-Z / VideoToolBox Folder / Demos / TestGDVideo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-04  |  14.5 KB  |  451 lines  |  [TEXT/KAHL]

  1. /* 
  2. TestGDVideo.c by Denis G. Pelli
  3. Tests all the documented Control and Status calls implemented in GDVideo.c
  4. The calls are documented in Designing Cards and Drivers, 3rd Edition.
  5.  
  6. The main purpose of this program is to find bugs in video drivers. If you do
  7. find a bug that isn't already listed in the table at the end of “Video synch”
  8. then please send it to denis_pelli@isr.syr.edu 
  9.  
  10. Unfortunately, the most common way to discover a new bug is for this program to
  11. crash. Please report crashes to denis_pelli@isr.syr.edu
  12.  
  13. BUGS:
  14.  
  15. HISTORY:
  16. 8/11/89    dgp    wrote it
  17. 3/23/90    dgp    introduced special case conditionals to skip tests known to crash
  18.             particular drivers.
  19. 3/23/90    dgp    made it compatible with MPW C, as a tool.
  20. 3/24/90    dgp    made some of the printouts less cryptic.
  21. 3/31/90    dgp    introduced RestoreDeviceClut after SetMode call.
  22. 7/12/90    dgp    tidied up the initial printf
  23. 7/19/90    dgp    Renamed VideoTest.c 
  24.             Open & close a window on each screen and DrawMenuBar()
  25.             so that QuickDraw will restore each screen.
  26. 7/28/90    dgp    italicized name of book.
  27. 9/9/90    dgp    Added quit by Command-. for graceful exit from bad situations.
  28. 10/17/90 dgp Removed unused variables. Replaced TRUE & FALSE by 1 & 0.
  29. 10/20/90    dgp    Apple has renamed the control and status calls, so I followed suit:
  30.                 GDGetPageBase replaces GDGetBaseAddr
  31.                 GDReset replaces GDInit
  32.                 GDGrayPage replace GDGrayScreen
  33.                 GDGetPageCnt replaces GDGetPages
  34. 10/22/90 dgp Print out number of pages for all modes, not just current mode.
  35.          dgp Restore clut manually since RestoreDeviceClut() doesn't
  36.              work on NuVista.
  37. 10/28/90 dgp Only test GetInterrupt & SetInterrupt if System is 6.05 or higher. This
  38.             avoids SetInterrupt() crash on old Apple TFB video driver.
  39. 2/12/91    dgp    Preceded GDGrayPage() call by GDSetMode() to cure crash when running
  40.             program immediately after rebooting. Mysterious.
  41.             Added SelectWindow() at end of program.
  42. 3/9/91    dgp    Print out mode names.
  43. 4/15/91    dgp    Make sure that new palette manager exists before calling RestoreDeviceClut.
  44.             Thanks to Chuck Stein for alerting me to the bug.
  45. 6/6/91    dgp    Time and print out how long GDSetEntries takes.
  46. 8/24/91    dgp    Made compatible with THINK C 5.0.
  47. 1/19/92    dgp    Cosmetic improvements to the printout.
  48. 2/25/92    dgp    Put timing info in bold.
  49. 8/22/92    dgp Display results of calling GDFrameRate() and GDFramesPerClutUpdate().
  50. 8/27/92    dgp    replace SysEnvirons() by Gestalt()
  51. 12/17/92 dgp enhanced to work with any dac size.
  52. 12/30/92 dgp Use GDClutSize() to determine clut size.
  53. 1/6/93    dgp    Tidied up the GetEntries/SetEntries code, now that we don't have
  54.             to test for the Mac IIci driver.
  55.             Skip GetEntries on Relax driver.
  56. 1/7/93 dgp    1.1 First numbered version.
  57. 1/18/93    dgp    Renamed ModeName() to GDModeName().
  58. 1/18/93    dgp    Moved the code that checked for bad drivers into GDGetEntries() in GDVideo.c,
  59.             where it belongs.
  60. 2/1/93    dgp Report whether driver is RAM- or ROM-based.
  61. 2/5/93    dgp    1.2. Recompiled with latest version of GDVideo, which now supports
  62.             patching of Mac IIci ROM-based driver.
  63. 2/6/93    dgp    1.3. Report ROM version, if driver is ROM-based.
  64. 2/7/93    dgp    1.4. Recompiled after fixing endless loop in PatchMacIIciVideoDriver
  65.             in GDVideo.c
  66. 2/18/93    dgp    1.5 Made compatible with PowerBook 160, by omitting call to GDSetInterrupt.
  67. 2/22/93    dgp    1.6 No longer assume that driver uses a version 0 gamma table.
  68. */
  69.  
  70. #define GAMMA_TABLE    1 /* TRUE or FALSE. Printout of gamma table. */
  71. #define VERSION "1.6"
  72.  
  73. #include "VideoToolbox.h"
  74. #include <assert.h>
  75. #include <Files.h>
  76. #if THINK_C
  77.     #include <LoMem.h>
  78. #else
  79.     short MBarHeight : 0xBAA;
  80. #endif
  81. #include <Menus.h>
  82.  
  83. int PatchMacIIciVideoDriver(void);
  84. #define dRAMBased        0x0040
  85.  
  86. #define SCREENS 8
  87.  
  88. void main(void);
  89. void Error(int error);
  90.  
  91. EventRecord theEvent;
  92.  
  93. void main()
  94. {
  95.     static WindowPtr window[SCREENS],oldPort;
  96.     static ColorSpec myTable[1024];    // Enough for 10-bit dacs
  97.     ColorSpec black={0,0,0,0};
  98.     WindowPtr theWindow;
  99.     GDHandle device;
  100.     short i,j,error,screen,ctSize,mode,page,pages,start,count,pixelSize,type,clutSize;
  101.     short textSize=12,dacSize,dataSize,dataCnt,fontNumber,newFontNumber,where;
  102.     short gammaDataWidth;
  103.     long systemVersion=0;
  104.     Boolean flag,keepWaiting;
  105.     GammaTbl *gamma=NULL,*myGamma=NULL;
  106.     char *name;
  107.     Ptr baseAddr;
  108.     Rect myRect;
  109.     double f;
  110.     unsigned char *byte;
  111.     unsigned short *word;
  112.     Boolean patch;
  113.     char typeName[][16]={"clutType","fixedType","directType"};
  114.     char modeName[][18]={"oneBitMode","twoBitMode","fourBitMode","eightBitMode"
  115.         ,"sixteenBitMode","thirtyTwoBitMode"};
  116.     AuxDCE **auxDCEHandle;
  117.     long size;
  118.     Ptr ptr;
  119.     long romSize,romVersion;
  120.             
  121.     Require(gestalt8BitQD);
  122.     InitGraf(&qd.thePort);
  123.     InitFonts();
  124.     InitWindows();
  125.     InitCursor();
  126.     GetPort(&oldPort);
  127.     _atexit(RestoreCluts);
  128.     patch=PatchMacIIciVideoDriver();
  129.     for(screen=0;screen<SCREENS;screen++){
  130.         SetPort(oldPort);
  131.         device = GetScreenDevice(screen);
  132.         if(device == NULL) break;
  133.  
  134.         /*
  135.         For reasons that I don't understand, calling GDGrayPage() first,
  136.         immediately after rebooting, results in a crash when using an Apple's
  137.         old "Toby" video card. Preceding the call by
  138.         a call to GDSetMode() cures the symptom. Later calls to GDGrayPage()
  139.         seem to always work fine. Presumably something is not properly initialized
  140.         in the Apple video card driver. (Toby card driver version 4.)
  141.         */
  142.         error=GDGetMode(device,&mode,&page,&baseAddr);
  143.         error=GDSetMode(device,mode,page,&baseAddr);
  144.         if(NewPaletteManager())RestoreDeviceClut(device);
  145.         
  146.         error=GDGrayPage(device,page);
  147.         if(screen==0)DrawMenuBar();    /* restore menu bar after GrayScreen */
  148.  
  149.         /* Open window */
  150.         myRect = (*device)->gdRect;    /* rect of desired screen in global coordinates */
  151.         if(screen==0)myRect.top+=MBarHeight;        /* allow for menu bar */
  152.         myRect.top+=17;                                /* allow for title bar */
  153.         InsetRect(&myRect,1,1);
  154.         name=GDCardName(device);
  155.         CtoPstr(name);
  156.         window[screen]=
  157.             NewCWindow(NULL,&myRect,(unsigned char *)name,TRUE,documentProc,(WindowPtr) -1L,TRUE,123L);
  158.  
  159.         /* Write in window */
  160.         SetPort(window[screen]);
  161.         myRect=window[screen]->portRect;
  162.         GetFNum("\pTimes",&fontNumber);
  163.         TextFont(fontNumber);
  164.         TextSize(textSize);
  165.         DrawPrintf("\n");
  166.         if(screen==0)DrawPrintf("Welcome to TestGDVideo " VERSION ". Now testing all your video drivers."
  167.         " Please report any crash to denis_pelli@isr.syr.edu\n");
  168.  
  169.         DrawPrintf("Driver: %#s version %d",GDName(device),GDVersion(device));
  170.         auxDCEHandle = (AuxDCE **) GetDCtlEntry((*device)->gdRefNum);
  171.         if((**auxDCEHandle).dCtlFlags & dRAMBased){
  172.             /* RAM-based driver. */
  173.             size=GetHandleSize((Handle)(**auxDCEHandle).dCtlDriver);
  174.             DrawPrintf(", occupying %ld bytes in RAM.",size);
  175.         }else{
  176.             /* ROM-based driver. */
  177.             ptr=(**auxDCEHandle).dCtlDriver;
  178.             Gestalt(gestaltROMSize,&romSize);
  179.             Gestalt(gestaltROMVersion,&romVersion);
  180.             DrawPrintf(", at 0x%lx in ROM. %ld K ROM version %ld (%ld)."
  181.                 ,ptr,romSize/1024,romVersion%256,(romVersion/256));
  182.         }
  183.         DrawPrintf("\n");
  184.         if(GetDeviceSlot(device)>=0)DrawPrintf("Slot: %d\n",GetDeviceSlot(device));
  185.         else DrawPrintf("Slot: none\n");
  186.     
  187.         DrawPrintf("GrayPage: ");
  188.         if(error) Error(error);
  189.         else DrawPrintf("ok\n");
  190.  
  191.         DrawPrintf("GetMode: ");
  192.         error=GDGetMode(device,&mode,&page,&baseAddr);
  193.         if(error) Error(error);
  194.         else DrawPrintf("%s page %d base address 0x%lX\n",GDModeName(mode),page,baseAddr);
  195.     
  196.         DrawPrintf("SetMode: ");
  197.         error=GDSetMode(device,mode,page,&baseAddr);
  198.         if(error) Error(error);
  199.         else DrawPrintf("ok\n");
  200.  
  201.         /* 
  202.             SetMode at one time had the annoying side effect of 
  203.             setting the clut to uniform gray, so let's restore the clut.
  204.         */
  205.         GDRestoreDeviceClut(device);
  206.  
  207.         for(i=oneBitMode;i<=thirtyTwoBitMode;i++){
  208.             DrawPrintf("GetPageCnt: ");
  209.             error=GDGetPageCnt(device,i,&pages);
  210.             if(error) DrawPrintf("%s n/a\n",GDModeName(i));
  211.             else DrawPrintf("%s has %d pages available\n",GDModeName(i),pages);
  212.         }
  213.  
  214.         DrawPrintf("GetPageBase: ");
  215.         page=0;    /* Ask for first page */
  216.         error=GDGetPageBase(device,page,&baseAddr);
  217.         if(error) Error(error);
  218.         else DrawPrintf("%s page %d base address 0x%lX\n",GDModeName(mode),page,baseAddr);
  219.         if(pages>1){
  220.             DrawPrintf("GetPageBase: ");
  221.             page=1;    /* Ask for second page */
  222.             error=GDGetPageBase(device,page,&baseAddr);
  223.             if(error) Error(error);
  224.             else DrawPrintf("%s page %d base address 0x%lX\n"
  225.                 ,GDModeName(mode),page,baseAddr);
  226.         }
  227.     
  228.         DrawPrintf("GetGray: ");
  229.         error=GDGetGray(device,&flag);
  230.         if(error) Error(error);
  231.         else DrawPrintf("flag %d\n",flag);
  232.     
  233.         DrawPrintf("SetGray: ");
  234.         flag=0;
  235.         error=GDSetGray(device,flag);
  236.         if(error) Error(error);
  237.         else DrawPrintf("ok\n");
  238.     
  239.         /* GetInterrupt crashes the NuVista driver.  */
  240.         if(!EqualString("\p.Display_Video_NuVista",GDName(device),0,0)){
  241.             /* SetInterrupt crashes the old Apple driver.  */
  242.             if(systemVersion>=0x605){
  243.                 DrawPrintf("GetInterrupt: ");
  244.                 error=GDGetInterrupt(device,&flag);
  245.                 if(error) Error(error);
  246.                 else DrawPrintf("%d\n",flag);
  247.         
  248.                 if(0){
  249.                     // crashes built-in video on PowerBook 160
  250.                     DrawPrintf("SetInterrupt: ");
  251.                     error=GDSetInterrupt(device,flag);
  252.                     if(error) Error(error);
  253.                     else DrawPrintf("ok\n");
  254.                 }
  255.             }
  256.             else DrawPrintf("•••••Skipping GetInterrupt & SetInterrupt.\n");
  257.         }
  258.         else DrawPrintf("•••••Skipping GetInterrupt & SetInterrupt to avoid known bug in %s.\n",GDCardName(device));
  259.  
  260.         DrawPrintf("GetGamma: ");
  261.         error=GDGetGamma(device,&gamma);
  262.         if(error) Error(error);
  263.         else DrawPrintf("gamma table indicates that the video card has %d-bit dacs, "
  264.             "and %d entries in its clut.\n"
  265.             ,gamma->gDataWidth,gamma->gDataCnt);
  266.         if(!error){
  267.             DrawPrintf("gVersion %d, gType %d, gFormulaSize %d, gChanCnt %d\n"
  268.             ,gamma->gVersion,gamma->gType,gamma->gFormulaSize,gamma->gChanCnt);
  269.         }
  270.         if(!error && GAMMA_TABLE // printout of gamma table is optional
  271.                 && gamma->gVersion==0 && gamma->gType==0){
  272.             GetFNum("\pMonaco",&newFontNumber);
  273.             TextFont(newFontNumber);
  274.             TextSize(9);
  275.             byte=(unsigned char *)gamma->gFormulaData+gamma->gFormulaSize;
  276.             word=(unsigned short *)byte;
  277.             DrawPrintf("Gamma Table:\n");
  278.             for(i=0;i<gamma->gDataCnt;i+=64) {
  279.                 DrawPrintf("%3d: ",i);
  280.                 if(gamma->gDataWidth<=8)
  281.                     for(j=0;j<64;j++) DrawPrintf(" %3u",byte[i+j]);
  282.                 else
  283.                     for(j=0;j<64;j++) DrawPrintf(" %3u",word[i+j]);
  284.                 DrawPrintf("\n");
  285.             }
  286.             TextFont(fontNumber);
  287.             TextSize(textSize);
  288.         }
  289.         if(!error)gammaDataWidth=gamma->gDataWidth;
  290.         else gammaDataWidth=0;
  291.         
  292.         DrawPrintf("SetGamma: ");
  293.         if(gamma==NULL){
  294.             // Get the dac's size from the current gamma table.
  295.             if(gamma!=NULL){
  296.                 dacSize=gamma->gDataWidth;
  297.                 dataCnt=gamma->gDataCnt;
  298.             }
  299.             else{ // The driver won't tell us, so assume 8-bit dacs.
  300.                 dacSize=8;
  301.                 dataCnt=1L<<dacSize;
  302.             }
  303.             if(dacSize<=8)dataSize=1;
  304.             else dataSize=2;
  305.             myGamma=(GammaTbl *)NewPtr(sizeof(GammaTbl)+dataCnt*dataSize);
  306.             assert(myGamma!=NULL);
  307.             myGamma->gVersion=0;
  308.             myGamma->gType=0;
  309.             myGamma->gFormulaSize=0;
  310.             myGamma->gChanCnt=1;
  311.             myGamma->gDataCnt=dataCnt;
  312.             myGamma->gDataWidth=dacSize;
  313.             byte=(unsigned char *)myGamma->gFormulaData+myGamma->gFormulaSize;
  314.             word=(unsigned short *)byte;
  315.             if(myGamma->gDataWidth<=8)
  316.                 for(i=0;i<myGamma->gDataCnt;i++) byte[i]=i;
  317.             else
  318.                 for(i=0;i<myGamma->gDataCnt;i++) word[i]=i;
  319.             gamma=myGamma;
  320.         }else myGamma=NULL;
  321.         error=GDSetGamma(device,gamma);
  322.         if(error) Error(error);
  323.         else DrawPrintf("ok.\n");
  324.         if(myGamma!=NULL){
  325.             DisposPtr((Ptr)myGamma);
  326.             myGamma=NULL;
  327.         }
  328.     
  329.         // GetEntries
  330.         start=0;
  331.         count=GDClutSize(device)-1;
  332.         if(count>sizeof(myTable)/sizeof(myTable[0])-1)
  333.             count=sizeof(myTable)/sizeof(myTable[0])-1;
  334.         DrawPrintf("GetEntries: ");
  335.         error=GDGetEntries(device,start,count,myTable);
  336.         if(error)Error(error);
  337.         else DrawPrintf("ok\n");
  338.         
  339.         // SetEntries
  340.         count=GDClutSize(device)-1;
  341.         switch((*device)->gdType){
  342.             case clutType:
  343.                 DrawPrintf("SetEntries: ");
  344.                 error=GDSetEntries(device,0,count,((**(**(**device).gdPMap).pmTable)).ctTable);
  345.                 if(error)Error(error);
  346.                 else DrawPrintf("ok\n");
  347.                 break;
  348.             case directType:
  349.                 DrawPrintf("DirectSetEntries: ");
  350.                 error=GDDirectSetEntries(device,0,0,&black);
  351.                 if(error)Error(error);
  352.                 else DrawPrintf("ok\n");
  353.                 break;
  354.             case fixedType:
  355.                 DrawPrintf("The clut cannot be modified.\n");
  356.                 break;
  357.         }
  358.         
  359.         // Miscellaneous
  360.         clutSize=GDClutSize(device);
  361.         pixelSize=1<<(mode&7);
  362.         type=(*device)->gdType;
  363.         DrawPrintf("Currently in %s, pixelSize %d bits, clutSize %d entries, %s"
  364.             ,modeName[mode&7],pixelSize,clutSize,typeName[type]);
  365.         if(gammaDataWidth!=0)DrawPrintf(", dacSize %d bits",gammaDataWidth);
  366.         DrawPrintf(".\n");
  367.  
  368.         TextFace(bold);
  369.         f=GDFrameRate(device);
  370.         DrawPrintf("%.1f Hz frame rate (%.1f ms).\n",f,1000.0/f);
  371.         if((*device)->gdType!=fixedType){
  372.             if(mode<sixteenBitMode)name="SetEntries";
  373.             else name="DirectSetEntries";
  374.             DrawPrintf("Repeatedly loading the clut, by calling %s(), "
  375.                 "takes %.2f frame each time.\n"
  376.                 ,name,GDFramesPerClutUpdate(device,0));
  377.             f=GDClutUpdateRate(device,0);
  378.             DrawPrintf("%.1f Hz clut update rate (%.1f ms).\n",f,1000.0/f);
  379.         }
  380.         TextFace(0);
  381.         
  382.         if(0){
  383.             /* I haven't found any use for these calls, so skip 'em */
  384.             DrawPrintf("GetDefaultMode: ");
  385.             error=GDGetDefaultMode(device,&mode);
  386.             if(error) Error(error);
  387.             else DrawPrintf("0x%X\n",mode);
  388.         
  389.             DrawPrintf("SetDefaultMode: ");
  390.             error=GDSetDefaultMode(device,mode);
  391.             if(error) Error(error);
  392.             else DrawPrintf("ok\n");
  393.         }
  394.         if(patch && EqualString("\p.Display_Video_Apple_RBV1",GDName(device),TRUE,FALSE))
  395.             DrawPrintf(
  396.             "This Mac IIci video driver has been patched (until reboot) to fix a bug\n"
  397.             "that prevents reading the clut. The version number was changed from 0 to %d.\n"
  398.             ,GDVersion(device));
  399.     }
  400.     SelectWindow(window[0]);
  401.     SetPort(window[0]);
  402.     DrawPrintf(
  403.         "This completes the test of the known Control and Status calls for each\n"
  404.         "of your video devices. For an explanation of what these calls do, see\n"
  405.         "Apple’s book ");
  406.     TextFace(italic);
  407.     DrawPrintf("Designing Cards and Drivers,");
  408.     TextFace(0);
  409.     DrawPrintf(" 3rd Ed., Addison Wesley, Chapter 9.\n");
  410.     TextFace(bold);
  411.     DrawPrintf("Quit by closing any window, or hitting Command-.\n");
  412.     do{
  413.         keepWaiting=1;
  414.         while(!GetNextEvent(mDownMask+keyDownMask,&theEvent));
  415.         switch(theEvent.what){
  416.         case mouseDown:
  417.             where=FindWindow(theEvent.where,&theWindow);
  418.             switch(where){
  419.             case inContent:
  420.             case inDrag:
  421.             case inGrow:
  422.             case inGoAway:
  423.                 SelectWindow(theWindow);
  424.             }
  425.             if(where==inGoAway) keepWaiting = !TrackGoAway(theWindow,theEvent.where);
  426.             break;
  427.         case keyDown:
  428.             if(theEvent.modifiers & cmdKey) switch(theEvent.message & charCodeMask) {
  429.                 case '.':
  430.                 case 'w':
  431.                 keepWaiting=0;
  432.             }
  433.             break;
  434.         }
  435.     } while (keepWaiting);
  436.     SetPort(oldPort);
  437.     for(i=0;i<screen;i++)DisposeWindow(window[i]);
  438.     _exit(0);
  439. }
  440.  
  441. void Error(int error)
  442. {
  443.     switch(error){
  444.     case -17:
  445.     case -18:
  446.         DrawPrintf("n/a\n");
  447.         break;
  448.     default:
  449.         DrawPrintf("error %d\n",error);
  450.     }
  451. }